package com.user.util;

import com.google.common.base.Charsets;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;

import java.security.MessageDigest;

/**
 * 类简述：MD5 加密工具
 * @author  mac.ma
 * @version  2017/9/25
 */
public final class MD5Util {

    //private static final String MD5_PREFIX = "b7038caf306dfc3c4b939b3d91cc6b88";

    private static final ThreadLocal<MD5Util> local = new ThreadLocal<MD5Util>();

    private MD5Util() {
        super();
    }

    public static MD5Util getEncrypt() {
        MD5Util encrypt = local.get();
        if (encrypt == null) {
            encrypt = new MD5Util();
            local.set(encrypt);
        }
        return encrypt;
    }



    /**
    * 简述： 对字符串进行MD5加密，并返回加密后字符串（小写）
    * @author  mac.ma
     * @param src
    * @return java.lang.String
    */
    public static String encrypt(String src) {
        byte[] source=src.getBytes();
        String s = null;
        char hexDigits[] = {       // 用来将字节转换成 16 进制表示的字符
                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',  'e', 'f'};
        try
        {
            MessageDigest md = MessageDigest.getInstance( "MD5" );
            md.update( source );
            byte tmp[] = md.digest();          // MD5 的计算结果是一个 128 位的长整数，
            // 用字节表示就是 16 个字节
            char str[] = new char[16 * 2];   // 每个字节用 16 进制表示的话，使用两个字符，
            // 所以表示成 16 进制需要 32 个字符
            int k = 0;                                // 表示转换结果中对应的字符位置
            for (int i = 0; i < 16; i++) {          // 从第一个字节开始，对 MD5 的每一个字节
                // 转换成 16 进制字符的转换
                byte byte0 = tmp[i];                 // 取第 i 个字节
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];  // 取字节中高 4 位的数字转换,
                // >>> 为逻辑右移，将符号位一起右移
                str[k++] = hexDigits[byte0 & 0xf];            // 取字节中低 4 位的数字转换
            }
            s = new String(str);                                 // 换后的结果转换为字符串

        }catch( Exception e )
        {
            e.printStackTrace();
        }
        return s;
    }

    /**
     * 简述： 对字符串进行MD5加密，并返回加密后字符串（大写）
     *
     * @param source
     * @return java.lang.String
     */
    public static String MD5(String source) {
        Hasher hasher = Hashing.md5().newHasher();
        hasher.putString(source, Charsets.UTF_8);
        return hasher.hash().toString().toUpperCase();
    }

    /**
     * 简述： 两重加密，针对前端登录密码加密 先MD5 再 SHA256
     *
     * @param source
     * @return
     */
    public static String encryptPassword(String source) {
        String second = MD5(source);
        Hasher sha256 = Hashing.sha256().newHasher();
        sha256.putString(second, Charsets.UTF_8);
        return sha256.hash().toString().toUpperCase();
    }


}
